#include "ModuleDescriptorMatcher.h"

////////////////////////////////////////////////////////////////////////////////
void ModuleDescriptorMatcher::init(QCVModuleHandlerInterface * parent)
{
  this->parent=parent;
  
  
	win=new QWidget();
  view=new QLabel(win);
  layout=new QVBoxLayout(win);
  
	auto_capture=new QCheckBox("Auto capture");
	auto_capture->setChecked(false);

	pb_capture=new QPushButton("capture",win);
	threshold=new QDoubleSpinBox(win);
	threshold->setValue(0.5);
  threshold->setSingleStep(0.1);
	threshold->setPrefix("distance_max=");

  layout->addWidget(view);
	layout->addWidget(pb_capture);
	layout->addWidget(auto_capture);
	layout->addWidget(threshold);
	
  connect(pb_capture,SIGNAL(clicked()),this,SLOT(s_capture()));

	capturedDescriptors.create(0,0);
}
////////////////////////////////////////////////////////////////////////////////
void ModuleDescriptorMatcher::free()
{
  delete win;
}
//////////////////////////////////////////////////////////////////////////////// 
cv::Mat & ModuleDescriptorMatcher::process()
{
  for(int i=0;i<keypoints.rows;i++)
  {
    cv::circle(frame,cv::Point(keypoints(i,0),keypoints(i,1)),2,cv::Scalar(255,255,255));
  }
  
  for(int i=0;i<capturedKeyPoints.rows;i++)
  {
    cv::circle(capturedFrame,cv::Point(capturedKeyPoints(i,0),capturedKeyPoints(i,1)),2,cv::Scalar(255,255,255));
  } 
  
  cv::Mat globalView(frame.rows*2,frame.cols,CV_8UC3);
  globalView.setTo(0);
  cv::Mat roi=globalView(cv::Rect(0,0,frame.cols,frame.rows));
  frame.copyTo(roi);
  cv::Mat roi2=globalView(cv::Rect(0,frame.rows,frame.cols,frame.rows));
  capturedFrame.copyTo(roi2);
  
  //vconcat(frame,capturedFrame,globalView);<-pas comprendre
  
  cv::Mat_<int> links;
	cv::Mat_<float> dists;
	if(capturedDescriptors.cols>0 && descriptors.cols>0 && 
		 capturedDescriptors.rows>0 && descriptors.rows>0)
	{
		getFLANN(descriptors,capturedDescriptors,links,dists,32);
	}

	int nbbinded=0;  
	for(int i=0;i<links.rows;i++)
  {		
		if(dists(i,0)<threshold->value())
		{
			cv::line(globalView,
			cv::Point(capturedKeyPoints(i,0),capturedKeyPoints(i,1)+frame.rows),
			cv::Point(keypoints(links(i,0),0),keypoints(links(i,0),1)),
			cv::Scalar(0,255,0));
			nbbinded++;
		}
  }
  
	printf("MATCHER:Nombre de points Capturés=%d\n",capturedKeyPoints.rows);
	printf("MATCHER:Nombre de points Courant=%d\n",keypoints.rows);
	printf("MATCHER:Nombre de points Liés=%d\n",nbbinded);

	if(auto_capture->isChecked())
	{
		s_capture();
	}
  
  QImage qglobalView((uchar*)globalView.data,globalView.cols,globalView.rows,QImage::Format_RGB888);
  view->setPixmap(QPixmap::fromImage(qglobalView));
  
  //liste des liens avec les points 
  return globalView;
}
////////////////////////////////////////////////////////////////////////////////
void ModuleDescriptorMatcher::setInput(int n,const cv::Mat & m)
{
  if(n==0)
  {
    frame=m.clone();
  }
  else if(n==1)
  {
    descriptors=m.clone();
  }
  else if(n==2)
  {
    keypoints=m.clone();
  }	
}
////////////////////////////////////////////////////////////////////////////////
QWidget* ModuleDescriptorMatcher::widget()
{
  return win;
}
////////////////////////////////////////////////////////////////////////////////
QString ModuleDescriptorMatcher::getName()
{
  return trUtf8("Mise en correspondance de descripteurs");
}
////////////////////////////////////////////////////////////////////////////////
int ModuleDescriptorMatcher::nbInputs()
{
  return 3;
}
////////////////////////////////////////////////////////////////////////////////
QString ModuleDescriptorMatcher::getParams()
{
	return QString::number(auto_capture->isChecked())+tr(";")+
				 QString::number(threshold->value());
}
////////////////////////////////////////////////////////////////////////////////
bool ModuleDescriptorMatcher::setParams(QString params)
{
	QStringList params_list=params.split(";");
	if(params_list.size()==2)
	{
		auto_capture->setChecked(params_list[0].toInt());
		threshold->setValue(params_list[1].toFloat());
		
		return true;
	}
	else
	{
		return false;
	}
}
////////////////////////////////////////////////////////////////////////////////
QCVModuleInterface * ModuleDescriptorMatcher::clone()
{
	return new ModuleDescriptorMatcher;
}
////////////////////////////////////////////////////////////////////////////////
QString  ModuleDescriptorMatcher::help(int id)
{
  if(id==-2)
  {
    return tr("Ce module permet mettre en correspondances des descripteurs.");
  }
  else if(id==-1)
  {
    return tr("image");
  }
  else if(id==0)
  {
    return tr("image");
  }
  else if(id==1)
  {
    return tr("descripteurs");
  }
  else if(id==2)
  {
    return tr("keyspoints");
  }
	else
	{
		return tr("erreur");
	}
}
////////////////////////////////////////////////////////////////////////////////
void ModuleDescriptorMatcher::s_capture()
{
  capturedFrame=frame.clone();
  capturedDescriptors=descriptors.clone();
  capturedKeyPoints=keypoints.clone();
}
////////////////////////////////////////////////////////////////////////////////
Q_EXPORT_PLUGIN2(ModuleDescriptorMatcher_plugin,ModuleDescriptorMatcher);                                                                               
                                              
